/*
  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
  TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.

  Copyright (c) 2003-2009 PRO ACTIVE SAS - www.proactive-group.com
   
  Ref_Mif_UL.c
  ------------

  This is the reference applications that shows how to read/write data
  in a Philips MIFARE UltraLite tag.
  
  JDA 21/11/2003 : initial release
  JDA 10/01/2007 : fixed a few warnings when compiling under GCC
  JDA 19/02/2007 : replaced Mf500xxx calls by SPROX_xxxx

*/
#include "products/springprox/springprox.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
  SWORD rc;
  int i, j;
  char s_buffer[64];
  BYTE data[16];
  BYTE atq[2];
  BYTE sak[1];
  BYTE uid[12];
  BYTE uid_len = 12;
  BYTE page;

  char *device = NULL;

  if (argc > 1)
    device = argv[1];

  printf("SpringCard SDK for K531/SpringProx-CF/CSB Legacy\n");
  printf("\n");
  printf("NXP MIFARE ULTRALIGHT reference demo\n");
  printf("------------------------------------\n");
  printf("www.springcard.com\n\n");

  rc = SPROX_GetLibrary(s_buffer, sizeof(s_buffer));
  if (rc != MI_OK)
  {
    printf("Failed to get API version\n");
    goto done;
  }
  printf("API version : %s\n", s_buffer);
  printf("\n");

  /* Open reader */
  /* ----------- */

  rc = SPROX_ReaderOpen(device);
  if (rc != MI_OK)
  {
    printf("Reader not found\n");
    goto done;
  }

  rc = SPROX_ReaderGetDevice(s_buffer, sizeof(s_buffer));
  if (rc == MI_OK)
    printf("Reader found on %s\n", s_buffer);

  rc = SPROX_ReaderGetFirmware(s_buffer, sizeof(s_buffer));
  if (rc == MI_OK)
    printf("Reader firwmare is %s\n", s_buffer);

  /* Configure reader in ISO 14443-A mode */
  /* ------------------------------------ */
  rc = SPROX_SetConfig(CFG_MODE_ISO_14443_A);
  if (rc != MI_OK)
  {
    printf("Failed to configure the reader\n");
    goto close;
  }

  /* RF field ON */
  SPROX_ControlRF(TRUE);

  /* Select any tag in the ISO 14443-A RF field */
  /* ------------------------------------------ */
  rc = SPROX_A_SelectIdle(atq, uid, &uid_len, sak);
  if (rc != MI_OK)
  {
    printf("No available tag in RF field\n");
    goto close;
  }

  printf("Tag found: UID=");
  for (i = 0; i < uid_len; i++)
    printf("%02X", uid[i]);
  printf(" ATQ=%02X%02X SAK=%02X\n", atq[1], atq[0], sak[0]);

  if ((atq[1] != 0x00) || (atq[0] != 0x44))
  {
    printf("This is not a Mifare UltraLite tag\n");
    goto tag_halt;
  }

  /* Read pages 0 to 15 */
  printf("Reading 16 pages...\n");

  /* We read 4 pages at once */
  for (page = 0; page < 16; page += 4)
  {
    rc = SPROX_MifRead(NULL, page, data);
    if (rc != MI_OK)
    {
      printf("Failed to read at address %d\n", page);
      goto tag_halt;
    }
       
    for (i=0; i<4; i++)
    {
      printf("Page %02d : ", page + i);

      /* Hexadecimal display */      
      for (j=4*i; j<4*(i+1); j++)
        printf("%02X", data[j]);
        
      printf("   ");

      /* RAW display of ASCII printable data */
      for (j=4*i; j<4*(i+1); j++)
      {
        if (data[i] >= ' ')
          printf("%c", data[j]);
        else
          printf(".");
      }
        
      printf("\n");
    }
  }

  /* Write pages 4 to 15 */
  printf("Writing 11 pages...\n");

  for (page = 4; page < 16; page++)
  {
    memset(&data[0], page, 4);

    rc = SPROX_MifWrite(NULL, page, data);
    if (rc != MI_OK)
    {
      printf("Failed to write at address %d\n", page);
      goto tag_halt;
    }
    printf("Page %02d : OK\n", page);
  }

  goto tag_halt;

tag_halt:
  /* Halt the tag */
  rc = SPROX_A_Halt();
  if (rc != MI_OK)
  {
    printf("Failed to halt the tag\n");
    goto close;
  }

close:
  /* Close the reader */
  SPROX_ControlRF(FALSE);
  SPROX_ReaderClose();

done:
  /* Display last error */
  if (rc == MI_OK)
  {
    printf("Done\n");
  } else
  {
    printf("%s (%d)\n", SPROX_GetErrorMessage(rc), rc);
  }
  return 0;
}
